import random
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.views import View
from pip._vendor.urllib3.packages.six import BytesIO
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, redirect
from django.views.decorators.http import require_http_methods

from userapp.users.models import UserModel, CustomModel


# Create your views here.
@require_http_methods(['POST'])
def check_username(request):
    # 中间值
    result_data = {'valid': True}
    # 这里是用户注册的表单参数
    # 先获取页面的数据
    un = request.POST.get('username')
    # 查询数据库的数据进行对比数据
    user = UserModel.objects.filter(username=un)
    # 判断数据如果存在
    if user:
        # 如果数据库存在
        result_data['valid'] = False
    # 返回字典的对象
    return JsonResponse(result_data)


# 验证码路径
@require_http_methods(['GET'])
def generate_codee(request):
    # 定义变量 用于画面的背景颜色 、宽、 高
    bg_color = (random.randrange(20, 100), random.randrange(20, 100), random.randrange(100, 255))
    width = 120
    height = 38
    # 创建画面对象
    im = Image.new('RGB', (width, height), bg_color)
    # 创建画笔的颜色
    draw = ImageDraw.Draw(im)
    # 调用画笔的point()函数绘制噪声点
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill == fill)

    # 定义验证码的备选值
    str1 = 'ABCDEFGHIJKLMNOPQRSTUVXYZ0123456789'
    # 随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str1[random.randrange(0, len(str1))]

    # 绘制4个字
    # 构造字体对象 字体对象的路径：
    # font = ImageFont.truetype('ebrima.ttf', 10)
    font = ImageFont.truetype('static/font/ARIAL.TTF', 24)
    # 构造字体的颜色
    # fontcolor = (random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255))
    draw.text((5, -3), rand_str[0], font=font,
              fill=(random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255)))
    draw.text((25, -3), rand_str[1], font=font,
              fill=(random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255)))
    draw.text((50, -3), rand_str[2], font=font,
              fill=(random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255)))
    draw.text((75, -3), rand_str[3], font=font,
              fill=(random.randrange(0, 255), random.randrange(0, 255), random.randrange(0, 255)))
    # 释放画笔
    del draw
    request.session['verify_code'] = rand_str
    # 内存文件操作
    buf = BytesIO()
    # 将图片保存在内存中 文件类型：png
    im.save(buf, 'png')
    # 将内存中的图片数据返回给客户端 MIME类型为图片png
    return HttpResponse(buf.getvalue(), 'image/png')


# 验证码的验证
@require_http_methods(['POST'])
def verify_code(request):
    # 设置一个修改的值
    result_data = {'valid': True}
    code1 = request.POST.get('captcha')
    # 数据是保存在session中的，以key value形式的
    code2 = request.session['verify_code']
    # 判断是否相等
    if not code1 == code2:
        result_data['valid'] = False
    return JsonResponse(result_data)


#  注册提交
@require_http_methods(['POST'])
def submit_register(request):
    # 把浏览器表单里的数据接受了，保存到数据库中去
    user = UserModel.objects.create_user(username=request.POST.get('username'),
                                         password=request.POST.get('password'),
                                         email=request.POST.get('email'),
                                         phone=request.POST.get('phone'))
    # user.sex = request.POST['sex']
    user.save()
    # 返回成功数据
    result_data = {'code': 200}
    return JsonResponse(result_data)


# 登陆函数
@require_http_methods(['POST'])
def submit_login(request):
    # 免登陆验证
    day = int(request.POST.get('remember', '1'))
    # 登陆我们先要获取表单的数据  这是django自带的用户登陆验证
    user = auth.authenticate(request=request, username=request.POST['username'],
                             password=request.POST['password'])
    if user:
        print(user)
        # 这里是把登陆的session记录在数据库中去，前端数据拿着KEY去后段数据库中去获取数据
        auth.login(request, user)
        # 设置保存时间
        request.session.set_expiry(day * 24 * 60 * 60)
        return redirect('/videos/index/')
    return redirect('/users/login/')


# 播放列表
class UserListView(LoginRequiredMixin, View):
    def get(self, request):
        # 获取从浏览器传过来的页码
        page_num = request.GET.get('page', 1)
        # 从数据库中查询数据, 排除当前用户 select * from t_user where id != xxx
        # orm操作中： 不等于操作。 exclude不等于
        user_list = UserModel.objects.exclude(id=request.user.id)
        # 显示10条数据
        paginator = Paginator(user_list, 10)
        # 得到页码范围
        page_range = paginator.page_range
        try:
            page = paginator.page(page_num)
        except PageNotAnInteger:
            # 如果不存在就返回第一页
            page = paginator.page(1)
        except EmptyPage:
            # 如果出错就返回到最后一页面
            page = paginator.page(paginator.num_pages)
        # 查询当前用户已经关注的用户列表, 列表里面不是用户对象，而是用户ID, values_list:指定返回的字段[ (1,),(3,),(5,)]--> [1,3,5]
        focus_ids = CustomModel.objects.filter(itself_user__id=request.user.id).values_list('target_user__id',
                                                                                            flat=True)
        print(focus_ids)
        # 把列表中嵌套的元祖展开切一个列表
        # 往模板中传入数据
        return render(request, 'user_list.html',
                      {'user_page': page, 'page_range': page_range, 'current_page': page.number,
                       'focus_ids': focus_ids})


# 关注列表
@require_http_methods(['GET'])
def my_focus(request):
    # 从数据库中查询数据， ORM是一个懒加载的框架
    # 查询当前登录用户，所关注的用户的ID列表
    # ids = UserFocusModel.objects.filter(cur_user__id=request.user.id).values_list('focus_user__id', flat=True)
    ids = CustomModel.objects.filter(itself_user__id=request.user.id).values_list('target_user__id', flat=True)
    print(ids)
    user_list = UserModel.objects.filter(id__in=ids).all()
    return render(request, 'my_focus.html', {'user_list': user_list})


# 关注函数
@require_http_methods(['GET'])
def add_focus(request):
    # 添加关注
    focus_id = request.GET.get('focus_id')
    focus_user = UserModel.objects.get(id=focus_id)
    CustomModel.objects.create(itself_user=request.user, target_user=focus_user)
    return redirect('/users/list_user/')


# 用户信息
class UserInfoView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'user_info.html')

    # 修改用户信息
    def post(self, request):
        UserModel.objects.all()
        # 先获取页面的数据
        phone = request.POST.get('phone', None)
        email = request.POST.get('email', None)
        username = request.POST.get('username', None)
        sex = request.POST.get('sex', None)
        age = int(request.POST.get('age', 0))
        real_name = request.POST.get('real_name', None)
        nationality = request.POST.get('nationality', None)
        city = request.POST.get('city', None)
        user_icon = request.FILES.get('user_icon', None)
        print(user_icon)
        if not user_icon:
            # 这里可以修改成前端地址
            pk = request.user.id
            icon = UserModel.objects.filter(id=pk).values('user_icon')
            for item in icon:
                icon = item['user_icon']
                user_icon = icon
        # 对于FileField类型不能用update()去操作，update会失效因此使用save来实现这一功能
        current_user = request.user
        current_user.phone = phone
        current_user.email = email
        current_user.username = username
        current_user.sex = sex
        current_user.age = age
        current_user.real_name = real_name
        current_user.nationality = nationality
        current_user.city = city
        current_user.user_icon = user_icon
        # 保存
        current_user.save()
        self.get(request)
        return redirect('/users/user_info/')


@require_http_methods(['GET'])
def delete_focus(request):
    """取消关注"""
    focus_id = int(request.GET.get('focus_id'))
    current_user = request.user
    CustomModel.objects.filter(itself_user=current_user, target_user__id=focus_id).delete()
    print(f"删除+{focus_id}+成功")
    return redirect('/users/my_focus/')


# 退出登陆
@login_required(login_url='/users/login/')
def logout(request):
    auth.logout(request)
    return redirect('/users/login/')
